package coroutines

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun simple() : Flow<Int> = flow{
    for (i in 1..3){
        delay(100)
        println("Emitting $i")
        emit(i)
    }
}

suspend fun testAsFlow() = coroutineScope{
    arrayOf(1,2,3).asFlow().collect { println("flow of value = $it") }
}

suspend fun testDelay()  = coroutineScope {
    (1..3).asFlow().map {
        delay(1000L)
        "response from delay $it"
    }.collect {
        println(it)
    }
}

fun numbers() : Flow<Int> = flow {
    try {
        emit(1)
        emit(2)
        println("this line will not execute")
    }finally {
        println("Finally in numbers")
    }
}

fun main() = runBlocking {
    supervisorScope {
        withTimeoutOrNull(250){
            simple().collect { println(it) }
        }
    }
    println("Done")

//    testDelay()

    numbers().take(2).collect { println("it") }
    println("first = ${numbers().first()}")


    val sum = (1..2).asFlow().map { it * it }.reduce{a, b-> a+b}
    println("sum = $sum")
}